<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title></title>
  <!-- 
	#### 1. 在head 头部 导入需要的依赖信息
	 -->
	<!-- 百度地图基础库 使用自己的 ak 进行配置 -->
  <script type="text/javascript"
          src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=G1LFyjrNGIkns5OfpZnrCGAKxpycPLwb"
  ></script>
  <!-- 公共的文件代码 里面包含 地图初始化 和 实用样式 -->
  <script src="https://mapv.baidu.com/gl/examples/static/common.js"></script>
  <!-- 使用根据城市名称获取城市的坐标 -->
  <script type="text/javascript" src="https://mapv.baidu.com/build/mapv.js"></script>
  <!--使用mapvgl的时候需要引入-->
  <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.54/dist/mapvgl.min.js"></script>
  <!-- 使用飞线图层需要使用的依赖 -->
	<!-- 
	/*
	FlyLineLayer
	用来展示轨迹飞线图层，继承自Layer

	基于Threejs实现，使用前需要额外引入mapvgl.threelayers包
	*/

	 -->
  <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.53/dist/mapvgl.threelayers.min.js"></script>
  <style type="text/css">
    /*
		####  2. 进行全局样式的配置 
		*/
    html, body {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }

    #map_container {
      width: 100%;
      height: 100%;
    }
  </style>
</head>
<body>
<div id="map_container"></div>
<script type="text/javascript">
  var map = initBMap()
  var data = initData()
  setData(data)

  // 初始化百度地图
  /*
		#### 4. 使用commn.js中的initMap方法初始化一个地图
		
		4.1 这里初始化地图使用的是 https://mapv.baidu.com/gl/examples/static/common.js库中的initMap 函数它初始化完成一个地图之后会返回一个地图对象。

		4.2 在common.js 中有初始化地图公共的代码，但是其将地图容器的名称固定的写为 map_container，这里需要注意。
	*/
  function initBMap() {
    var map = initMap({
      // 切斜角度
      tilt: 0,
      // 地图的中心点坐标
      center: [108.154518, 36.643346],
      // 地图缩放比例
      zoom: 5,
      // 地图样式
      style: darkStyle
    })
    return map
  }

  // 准备数据源
  /*
		#### 5. 准备数据源
    fly2使用的是边绑定
	*/
  /*
  版本1：
    initData1()
    使用的是贝塞尔曲线
		数据中的每一个数据项代表一条贝塞尔曲线。
		贝赛尔曲线又由一些点构成，最后通过mapvgl的飞线图层FlyLineLayer创建一条条的飞线。
  */
  function initData1() {
			// 生成的数据信息
			var data = [];
			// 城市数据信息
			var citys = [
				'北京', '天津', '上海', '重庆', '石家庄', '太原', '呼和浩特', '哈尔滨', '长春',
				'沈阳', '济南', '南京', '合肥', '杭州', '南昌', '福州', '郑州', '武汉', '长沙', '广州',
				'南宁', '西安', '银川', '兰州', '西宁', '乌鲁木齐', '成都', '贵阳', '昆明', '拉萨', '海口'
			];
			var randomCount = 100; 
			var curve = new mapvgl.BezierCurve();

	    	// 构造数据
  	  		while (randomCount--) {

				/*
				###### 5.2 设置起点坐标和终点坐标
				
				*/
				// 获取每一个城市的中心点坐标 随机生成  在 所有城市范围内挑选 生成的随机数是 [0,cities.length] 创建开始开始城市和终点城市
				var startPoint = mapv.utilCityCenter.getCenterByCityName(citys[parseInt(Math.random() * citys.length, 10)]);
				var endPoint = mapv.utilCityCenter.getCenterByCityName(citys[parseInt(Math.random() * citys.length, 10)])
				/*
				22.通过 setOptions方法设置贝赛尔曲线的起点坐标和终点坐标
				*/
				curve.setOptions({
					start: [startPoint.lng, startPoint.lat],
					end: [endPoint.lng, endPoint.lat]
				});

				/*
				###### 5.3 生成贝塞尔曲线坐标集

				33.使用 getPoints()方法获取到生成的贝赛尔曲线坐标集。并将其设置到data数组中。
				*/
				var curveModelData = curve.getPoints();
				data.push({
					geometry: {
						type: 'LineString',
						coordinates: curveModelData
					},
					properties: {
						count: Math.random()
					}
				});
    		}
			return data;
		}


  /*
	#### 6. 设置数据源
	*/
  /*
  setData() 
  用贝塞尔曲线获得所有点的数据
  绘制线 静态的  LineLayer
  绘制点 运动的  LinePointLayer

  线的绘制和点的绘制数据是一样的

  LinePointLayer 官网没有，demo中可以看到
  https://mapv.baidu.com/gl/examples/editor.html#line-point.html
  */
  function setData1(data) {
   
    var view = new mapvgl.View({ map })

    var lineLayer = new mapvgl.LineLayer({
      color: 'rgba(55, 50, 250, 0.3)',
      blend: 'lighter'
    })
    view.addLayer(lineLayer)
    lineLayer.setData(data)


    var linePointLayer = new mapvgl.LinePointLayer({
      size: 8,
      speed: 20,
      color: 'rgba(255, 255, 0, 0.6)',
      animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_SMOOTH,
      shapeType: mapvgl.LinePointLayer.SHAPE_TYPE_CIRCLE,
      blend: 'lighter'
    })
    view.addLayer(linePointLayer)
    linePointLayer.setData(data)
  }

  /*
  总结，
  使用贝塞尔曲线获得的数据，绘制点和线，效果和fly差很多

  点的动画距离fly还差恩多？怎么解决？
  边绑定
  https://zhuanlan.zhihu.com/p/94155959

  我们发现简单地将该数据渲染后的结果航线纵横交错，穿梭在密集的城市当中，
  视觉上十分混乱，即难以看清细节，也不能发现航线的总体趋势。

  通过边绑定的方法降低图 5 的视觉混乱，
  从而清晰图的整体走势、结构，突出航线频繁的城市，
  它们可能是重要的交通枢纽，并展示更多的统计信息，以便观察者进行分析。
  

  fly放大可以看到明显的卡顿
  */



  /*
  使用边绑定
  */
  
  function initData() {
    var randomCount = 500

    /*
    node_data：所有的点
    必须有一个明确的点，
    第一个节点，即中心点位置，北京
    */
    /*  使用强制边绑定算法实现边的汇聚效果开始 */
    var node_data = [
      {
        x: 108.154518,
        y: 36.643346
      }
    ]
    /*
    edge_data：边的关系
    可以默认为空，点是501个，边是500个
    */
    // 边数据
    var edge_data = [
      {
        source: 1, //source：起点
        target: 0  //target：终点  0 指的是node_data中第0个位置
      }
    ]
    var cities = [
      '北京', '天津', '上海', '重庆', '石家庄', '太原', '呼和浩特', '哈尔滨', '长春', '沈阳', '济南', '南京', '合肥', '杭州', '南昌', '福州', '郑州', '武汉', '长沙', '广州', '南宁', '西安', '银川', '兰州', '西宁', '乌鲁木齐', '成都', '贵阳', '昆明', '拉萨', '海口'
    ]
    // 构造数据
    // 循环生成 随机个 点数据 和 边数据
    for (var i = 1; i < randomCount; i++) {
      /*
      随机的城市的经纬度坐标
      */
      var cityCenter = mapv.utilCityCenter.getCenterByCityName(cities[parseInt(Math.random() * cities.length)])
      /*
      左边位置不是全部都是省会城市，做了偏移，省会城市附近
      */
      //添加每一个点的数据
      node_data.push({
        // 这里让每个数据在渲染的时候是一种散列开的效果 是一个随机算法
        x: cityCenter.lng - 5 + Math.random() * 10, 
        y: cityCenter.lat - 5 + Math.random() * 10
      })
      /*
      从各个点指向0，中心点北京的位置
      */
      //边数据
      edge_data.push({
        source: parseInt(i * Math.random()),
        target: 0
      })
    }

    // 使用强制边绑定算法 进行强制边绑定调用该函数之后的结果是一个函数
    /*边绑定  mapv提供的方法*/
    var fbundling = mapv.utilForceEdgeBundling()
      .nodes(node_data)
      .edges(edge_data)
    // 调用得到的 bundling是一个 函数 调用这个函数返回 绑定结果集
    var results = fbundling()
    /* 强制边绑定算法结束 */

    var data = []
    // timeData没用上
    // var timeData = []

    for (var i = 0; i < results.length; i++) {
      // 线，可以理解成一条线上的所有数据
      var line = results[i] //线段数据
      console.log("----line----",line)
      /*
      line: length = 67
      [
        {x: 118.64077427188134, y: 31.116777657477265}
        {x: 118.52572909704892, y: 30.948688939572662}
        {x: 118.43686579823276, y: 30.818853698863588}
      ]
      */
      // 坐标
      var coordinates = []
      for (var j = 0; j < line.length; j++) {

        coordinates.push([line[j].x, line[j].y])

        // timeData.push({
        //   geometry: {
        //     type: 'LineString',
        //     coordinates: [line[j].x, line[j].y]
        //   },
        //   count: 1,
        //   time: j
        // })
      }


      console.log("--------coordinates-------",coordinates)
      /*
      [
        [113.69488814875075, 36.24448164533265],
        [113.66662746783645, 36.33837269116571],
        [113.65435494971966, 36.37914593242212],
        [113.62324165510667, 36.48251427585958],
        [113.57762795919368, 36.61862512652805],
        [113.5309411850541, 36.704665531432454],
      ]
      */





      /*
      LineLayer 官网案例

      data: [
        {
          geometry: {
              type: 'LineString',
              coordinates: [
                  [116.394191, 39.91334],
                  [116.417259, 39.913672]
                  ....
              ]
          }
        }
      ]

      LinePointLayer 官网demo的数据
      data:[
        {
          geometry: {
              type: 'LineString',
              coordinates: [
                [106.481201, 29.565882]
                [106.485306, 29.566432]
                [106.48863, 29.569464]
                [106.490687, 29.571341]
                [106.492456, 29.572958]
                ....
              ]
          }
        }
      ]
      
      */


      data.push({
        geometry: {
          type: 'LineString',
          coordinates: coordinates
        }
      })
     
    }

    console.log("--------data-------",data)

    /*

    data: LineLayer 的数据data
    [
      {
        geometry: {
          type: 'LineString',
          coordinates: [
            ......
          ]
        }
      },
      {
        geometry: {
          type: 'LineString',
          coordinates: [
            .....
          ]
        }
      }
      ....
    ]
    */

    return {
      pointData: timeData,
      lineData: data
    }
  }

  /*
  没有用上pointData
  */
  function setData({ pointData, lineData }) {
    console.log(pointData)
    var view = new mapvgl.View({ map })

    /*
    线是静态的 LineLayer
    */
    var lineLayer = new mapvgl.LineLayer({
      color: 'rgba(55, 50, 250, 0.3)',
      // 线出现重叠的时候进行高亮显示
      // 线在汇聚的时候出现白色的效果
      blend: 'lighter'
    })
    view.addLayer(lineLayer)
    lineLayer.setData(lineData)

    /*
    点是运动的 LinePointLayer
    官网api没有这个，在demo中可以看到
    */
    var linePointLayer = new mapvgl.LinePointLayer({
      size: 8,
      speed: 20,
      color: 'rgba(255, 255, 0, 0.6)',
      // animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_UNIFORM_SPEED, // 这个动画是匀速的
      animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_SMOOTH,// 动画类型
      shapeType: mapvgl.LinePointLayer.SHAPE_TYPE_CIRCLE,// 形状
      blend: 'lighter'
    })
    view.addLayer(linePointLayer)
    linePointLayer.setData(lineData)
  }

</script>

</body>
</html>
